﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Uniloader.Managers;
using Uniloader.Interface;
using Uniloader.Configuration;

namespace XamlTorrent
{
    /// <summary>
    /// Interaction logic for WindowNewDownload.xaml
    /// </summary>
    public partial class WindowNewDownload : Window
    {
        public WindowNewDownload()
        {
            InitializeComponent();

            AddCreateTaskUI();
        }

        /// <summary>
        /// Loads UI elements for creating tasks from each transfer manager.
        /// </summary>
        private void AddCreateTaskUI()
        {
            foreach (TransferManager mgr in ((App)App.Current).DownloadManagers)
            {
                ITaskUIFactory uiFactory = mgr as ITaskUIFactory;

                if (uiFactory == null) continue; // No UI for this one

                TaskUI[] taskUIgroup = uiFactory.CreateNewTaskUI();

                foreach (TaskUI taskUI in taskUIgroup)
                {
                    TabItem tabPage = new TabItem();
                    tabPage.Content = taskUI.Content;
                    tabPage.Header = taskUI.Header;

                    tabPages.Items.Add(tabPage);
                }
            }
        }

        // Validate all dependency objects in a window
        protected bool IsValid(object content, string indent)
        {
            DependencyObject node = tabPages.SelectedContent as DependencyObject;

            // Check if dependency object was passed
            if (node != null)
            {
                // Check if dependency object is valid.
                // NOTE: Validation.GetHasError works for controls that have validation rules attached 
                bool isValid = !Validation.GetHasError(node);
                if (!isValid)
                {
                    // If the dependency object is invalid, and it can receive the focus,
                    // set the focus
                    if (node is IInputElement) Keyboard.Focus((IInputElement)node);
                    return false;
                }
            }

            // If this dependency object is valid, check all child dependency objects
            foreach (object subnode in LogicalTreeHelper.GetChildren(node))
            {
                System.Diagnostics.Trace.Write(indent);
                System.Diagnostics.Trace.WriteLine(subnode);
                if (subnode is DependencyObject)
                {
                    // If a child dependency object is invalid, return false immediately,
                    // otherwise keep checking
                    if (!IsValid((DependencyObject)subnode, indent + "\t")) return false;
                }
            }


            //// If this dependency object is valid, check all child dependency objects
            //foreach (object child in LogicalTreeHelper.GetChildren(node))
            //{
            //    DependencyObject subNode = child as DependencyObject;

            //    if (subNode != null && !IsValid(subNode))
            //        return false;
            //}

            // All dependency objects are valid
            return true;
        }

        // Validate all dependency objects in a window
        bool IsValid(DependencyObject node)
        {
            // Check if dependency object was passed
            if (node != null)
            {
                // Check if dependency object is valid.
                // NOTE: Validation.GetHasError works for controls that have validation rules attached 
                bool isValid = !Validation.GetHasError(node);
                if (!isValid)
                {
                    // If the dependency object is invalid, and it can receive the focus,
                    // set the focus
                    if (node is IInputElement) Keyboard.Focus((IInputElement)node);
                    return false;
                }
            }

            // If this dependency object is valid, check all child dependency objects
            foreach (object subnode in LogicalTreeHelper.GetChildren(node))
            {
                if (subnode is DependencyObject)
                {
                    // If a child dependency object is invalid, return false immediately,
                    // otherwise keep checking
                    if (IsValid((DependencyObject)subnode) == false) return false;
                }
            }

            // All dependency objects are valid
            return true;
        }

        private void ButtonOk_Click(object sender, RoutedEventArgs e)
        {
            // make sure the control passes its validation, if applicable
            if (!IsValid(tabPages.SelectedContent as DependencyObject)) return;

            ITransferTaskFactory generator = tabPages.SelectedContent as ITransferTaskFactory;

            if (generator != null)
            {
                generator.CreateTask();

                DialogResult = true;
            }
            else
            {
                DialogResult = false;
            }

            Close();
        }

        private void ButtonCancel_Click(object sender, RoutedEventArgs e)
        {
            DialogResult = false;
            Close();
        }

        private void tabPages_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            UpdateButtons();
        }

        private void UpdateButtons()
        {
            btnOk.IsEnabled = (tabPages.SelectedContent is ITransferTaskFactory);
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            UpdateButtons();
        }
    }
}
